﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenTK;
using global::OpenTK.Graphics;
using global::OpenTK.Graphics.OpenGL;
using DDD.Core;

namespace DDD.OpenTK {
    /// <summary>
    /// DDDのEnumを拡張するクラス
    /// </summary>
    public static class EnumExtensions {
        /// <summary>
        /// <see cref="IndexType"/>を対応するOpenTKの型に変換します
        /// </summary>
        /// <param name="type">DDDの<see cref="IndexType"/>型</param>
        /// <returns>OpenTKの<seealso cref="global::OpenTK.Graphics.OpenGL.DrawElementsType"/>型</returns>
        public static global::OpenTK.Graphics.OpenGL.DrawElementsType ToGL (this IndexType type) {
            switch (type) {
                case IndexType.Byte: return global::OpenTK.Graphics.OpenGL.DrawElementsType.UnsignedByte;
                case IndexType.Short: return global::OpenTK.Graphics.OpenGL.DrawElementsType.UnsignedShort;
                case IndexType.UShort: return global::OpenTK.Graphics.OpenGL.DrawElementsType.UnsignedShort;
                case IndexType.Int: return global::OpenTK.Graphics.OpenGL.DrawElementsType.UnsignedInt;
                case IndexType.UInt: return global::OpenTK.Graphics.OpenGL.DrawElementsType.UnsignedInt;
                default: throw new NotImplementedException ("Sorry");
            }
        }

        /// <summary>
        /// <see cref="PrimitiveType"/>を対応するOpenTKの型に変換します
        /// </summary>
        /// <param name="type">DDDの<see cref="PrimitiveType"/>型</param>
        /// <returns>OpenTKの<seealso cref="global::OpenTK.Graphics.OpenGL.BeginMode"/>型</returns>
        public static global::OpenTK.Graphics.OpenGL.BeginMode ToGL (this PrimitiveType type) {
            switch (type) {
                case PrimitiveType.Line: return global::OpenTK.Graphics.OpenGL.BeginMode.Lines;
                case PrimitiveType.Triangle: return global::OpenTK.Graphics.OpenGL.BeginMode.Triangles;
                case PrimitiveType.Point: return global::OpenTK.Graphics.OpenGL.BeginMode.Points;
                default: throw new NotImplementedException ("Sorry");
            }
        }

        /// <summary>
        /// <see cref="PrimitiveType"/>を対応するOpenTKの型に変換します
        /// </summary>
        /// <remarks>
        /// フィードバックモードの時に使用します
        /// </remarks>
        /// <param name="type">DDDの<see cref="PrimitiveType"/>型</param>
        /// <returns>OpenTKの<seealso cref="global::OpenTK.Graphics.OpenGL.BeginFeedbackMode"/>型</returns>
        public static global::OpenTK.Graphics.OpenGL.BeginFeedbackMode ToGL2 (this PrimitiveType type) {
            switch (type) {
                case PrimitiveType.Line: return global::OpenTK.Graphics.OpenGL.BeginFeedbackMode.Lines;
                case PrimitiveType.Triangle: return global::OpenTK.Graphics.OpenGL.BeginFeedbackMode.Triangles;
                case PrimitiveType.Point: return global::OpenTK.Graphics.OpenGL.BeginFeedbackMode.Points;
                default: throw new NotImplementedException ("Sorry");
            }
        }

        /// <summary>
        /// <see cref="ComponentType"/>を対応するOpenTKの型に変換します
        /// </summary>
        /// <param name="type">DDDの<see cref="ComponentType"/>型</param>
        /// <returns>OpenTKの<seealso cref="global::OpenTK.Graphics.OpenGL.VertexAttribPointerType"/>型</returns>
        public static global::OpenTK.Graphics.OpenGL.VertexAttribPointerType ToGL (this ComponentType type) {
            switch (type) {
                case ComponentType.Byte: return global::OpenTK.Graphics.OpenGL.VertexAttribPointerType.UnsignedByte;
                case ComponentType.SByte: return global::OpenTK.Graphics.OpenGL.VertexAttribPointerType.Byte;
                case ComponentType.Short: return global::OpenTK.Graphics.OpenGL.VertexAttribPointerType.Short;
                case ComponentType.UShort: return global::OpenTK.Graphics.OpenGL.VertexAttribPointerType.UnsignedShort;
                case ComponentType.Int: return global::OpenTK.Graphics.OpenGL.VertexAttribPointerType.Int;
                case ComponentType.UInt: return global::OpenTK.Graphics.OpenGL.VertexAttribPointerType.UnsignedInt;
                case ComponentType.Float: return global::OpenTK.Graphics.OpenGL.VertexAttribPointerType.Float;
                default: throw new NotImplementedException ("Sorry");
            }
        }


        /// <summary>
        /// <see cref="DDD.Core.PixelFormat"/>を対応するOpenTKの型に変換します
        /// </summary>
        /// <remarks>
        /// 内部フォーマット型に変換するときに使用します
        /// </remarks>
        /// <param name="format">DDDの<see cref="DDD.Core.PixelFormat"/>型</param>
        /// <returns>OpenTKの<seealso cref="global::OpenTK.Graphics.OpenGL.PixelInternalFormat"/>型</returns>
        public static global::OpenTK.Graphics.OpenGL.PixelInternalFormat ToGL_InternalFormat (this DDD.Core.PixelFormat format) {
            switch (format) {
                case DDD.Core.PixelFormat.R8: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.R8;
                case DDD.Core.PixelFormat.R8i: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.R8i;
                case DDD.Core.PixelFormat.R8ui: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.R8ui;
                case DDD.Core.PixelFormat.R16: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.R16;
                case DDD.Core.PixelFormat.R16f: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.R16f;
                case DDD.Core.PixelFormat.R16i: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.R16i;
                case DDD.Core.PixelFormat.R16ui: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.R16ui;
                case DDD.Core.PixelFormat.R32f: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.R32f;
                case DDD.Core.PixelFormat.R32i: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.R32i;
                case DDD.Core.PixelFormat.R32ui: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.R32ui;

                case DDD.Core.PixelFormat.RG8: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rg8;
                case DDD.Core.PixelFormat.RG8i: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rg8i;
                case DDD.Core.PixelFormat.RG8ui: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rg8ui;
                case DDD.Core.PixelFormat.RG16: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rg16;
                case DDD.Core.PixelFormat.RG16f: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rg16f;
                case DDD.Core.PixelFormat.RG16i: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rg16i;
                case DDD.Core.PixelFormat.RG16ui: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rg16ui;
                case DDD.Core.PixelFormat.RG32f: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rg32f;
                case DDD.Core.PixelFormat.RG32i: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rg32i;
                case DDD.Core.PixelFormat.RG32ui: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rg32ui;

                case DDD.Core.PixelFormat.RGB8: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgb8;
                case DDD.Core.PixelFormat.RGB8i: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgb8i;
                case DDD.Core.PixelFormat.RGB8ui: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgb8ui;
                case DDD.Core.PixelFormat.RGB16: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgb16;
                case DDD.Core.PixelFormat.RGB16f: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgb16f;
                case DDD.Core.PixelFormat.RGB16i: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgb16i;
                case DDD.Core.PixelFormat.RGB16ui: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgb16ui;
                case DDD.Core.PixelFormat.RGB32f: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgb32f;
                case DDD.Core.PixelFormat.RGB32i: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgb32i;
                case DDD.Core.PixelFormat.RGB32ui: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgb32ui;

                case DDD.Core.PixelFormat.RGBA8: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgba8;
                case DDD.Core.PixelFormat.RGBA8i: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgba8i;
                case DDD.Core.PixelFormat.RGBA8ui: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgba8ui;
                case DDD.Core.PixelFormat.RGBA16: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgba16;
                case DDD.Core.PixelFormat.RGBA16f: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgba16f;
                case DDD.Core.PixelFormat.RGBA16i: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgba16i;
                case DDD.Core.PixelFormat.RGBA16ui: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgba16ui;
                case DDD.Core.PixelFormat.RGBA32f: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgba32f;
                case DDD.Core.PixelFormat.RGBA32i: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgba32i;
                case DDD.Core.PixelFormat.RGBA32ui: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgba32ui;

                case DDD.Core.PixelFormat.RGB9e5: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgb9E5;
                case DDD.Core.PixelFormat.R11G11B10f: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.R11fG11fB10f;
                case DDD.Core.PixelFormat.RGB10A2: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgb10A2;
                case DDD.Core.PixelFormat.RGB10A2ui: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgb10A2ui;

                case DDD.Core.PixelFormat.Depth: return global::OpenTK.Graphics.OpenGL.PixelInternalFormat.DepthComponent;
                default: throw new NotImplementedException ("Sorry");
            }
        }

        /// <summary>
        /// <see cref="DDD.Core.PixelFormat"/>を対応するOpenTKの型に変換します
        /// </summary>
        /// <param name="format">DDDの<see cref="DDD.Core.PixelFormat"/>型</param>
        /// <returns>OpenTKの<seealso cref="global::OpenTK.Graphics.OpenGL.PixelFormat"/>型</returns>
        public static global::OpenTK.Graphics.OpenGL.PixelFormat ToGL_Format (this DDD.Core.PixelFormat format) {
            switch (format) {
                case DDD.Core.PixelFormat.R8: return global::OpenTK.Graphics.OpenGL.PixelFormat.Red;
                case DDD.Core.PixelFormat.R8i: return global::OpenTK.Graphics.OpenGL.PixelFormat.RedInteger;
                case DDD.Core.PixelFormat.R8ui: return global::OpenTK.Graphics.OpenGL.PixelFormat.RedInteger;
                case DDD.Core.PixelFormat.R16: return global::OpenTK.Graphics.OpenGL.PixelFormat.Red;
                case DDD.Core.PixelFormat.R16f: return global::OpenTK.Graphics.OpenGL.PixelFormat.Red;
                case DDD.Core.PixelFormat.R16i: return global::OpenTK.Graphics.OpenGL.PixelFormat.RedInteger;
                case DDD.Core.PixelFormat.R16ui: return global::OpenTK.Graphics.OpenGL.PixelFormat.RedInteger;
                case DDD.Core.PixelFormat.R32f: return global::OpenTK.Graphics.OpenGL.PixelFormat.Red;
                case DDD.Core.PixelFormat.R32i: return global::OpenTK.Graphics.OpenGL.PixelFormat.RedInteger;
                case DDD.Core.PixelFormat.R32ui: return global::OpenTK.Graphics.OpenGL.PixelFormat.RedInteger;

                case DDD.Core.PixelFormat.RG8: return global::OpenTK.Graphics.OpenGL.PixelFormat.Rg;
                case DDD.Core.PixelFormat.RG8i: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgInteger;
                case DDD.Core.PixelFormat.RG8ui: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgInteger;
                case DDD.Core.PixelFormat.RG16: return global::OpenTK.Graphics.OpenGL.PixelFormat.Rg;
                case DDD.Core.PixelFormat.RG16f: return global::OpenTK.Graphics.OpenGL.PixelFormat.Rg;
                case DDD.Core.PixelFormat.RG16i: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgInteger;
                case DDD.Core.PixelFormat.RG16ui: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgInteger;
                case DDD.Core.PixelFormat.RG32f: return global::OpenTK.Graphics.OpenGL.PixelFormat.Rg;
                case DDD.Core.PixelFormat.RG32i: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgInteger;
                case DDD.Core.PixelFormat.RG32ui: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgInteger;

                case DDD.Core.PixelFormat.RGB8: return global::OpenTK.Graphics.OpenGL.PixelFormat.Rgb;
                case DDD.Core.PixelFormat.RGB8i: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgbInteger;
                case DDD.Core.PixelFormat.RGB8ui: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgbInteger;
                case DDD.Core.PixelFormat.RGB16: return global::OpenTK.Graphics.OpenGL.PixelFormat.Rgb;
                case DDD.Core.PixelFormat.RGB16f: return global::OpenTK.Graphics.OpenGL.PixelFormat.Rgb;
                case DDD.Core.PixelFormat.RGB16i: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgbInteger;
                case DDD.Core.PixelFormat.RGB16ui: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgbInteger;
                case DDD.Core.PixelFormat.RGB32f: return global::OpenTK.Graphics.OpenGL.PixelFormat.Rgb;
                case DDD.Core.PixelFormat.RGB32i: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgbInteger;
                case DDD.Core.PixelFormat.RGB32ui: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgbInteger;

                case DDD.Core.PixelFormat.RGBA8: return global::OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
                case DDD.Core.PixelFormat.RGBA8i: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgbaInteger;
                case DDD.Core.PixelFormat.RGBA8ui: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgbaInteger;
                case DDD.Core.PixelFormat.RGBA16: return global::OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
                case DDD.Core.PixelFormat.RGBA16f: return global::OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
                case DDD.Core.PixelFormat.RGBA16i: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgbaInteger;
                case DDD.Core.PixelFormat.RGBA16ui: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgbaInteger;
                case DDD.Core.PixelFormat.RGBA32f: return global::OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
                case DDD.Core.PixelFormat.RGBA32i: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgbaInteger;
                case DDD.Core.PixelFormat.RGBA32ui: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgbaInteger;

                case DDD.Core.PixelFormat.RGB9e5: return global::OpenTK.Graphics.OpenGL.PixelFormat.Rgb;
                case DDD.Core.PixelFormat.R11G11B10f: return global::OpenTK.Graphics.OpenGL.PixelFormat.Rgb;
                case DDD.Core.PixelFormat.RGB10A2: return global::OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
                case DDD.Core.PixelFormat.RGB10A2ui: return global::OpenTK.Graphics.OpenGL.PixelFormat.RgbaInteger;

                case DDD.Core.PixelFormat.Depth: return global::OpenTK.Graphics.OpenGL.PixelFormat.DepthComponent;

                default: throw new NotImplementedException ("Sorry");
            }
        }

        /// <summary>
        /// DDDの<see cref="DDD.Core.PixelFormat"/>型オブジェクトをOpenTKのアライメントサイズ(ようはバイト数)に変換します
        /// </summary>
        /// <param name="format"><see cref="DDD.Core.PixelFormat"/>型オブジェクト</param>
        /// <returns>バイト数</returns>
        public static int ToGL_Alignment (this DDD.Core.PixelFormat format) {
            switch (format) {
                case DDD.Core.PixelFormat.R8: return 1;
                case DDD.Core.PixelFormat.R8i: return 1;
                case DDD.Core.PixelFormat.R8ui: return 1;
                case DDD.Core.PixelFormat.R16: return 2;
                case DDD.Core.PixelFormat.R16f: return 2;
                case DDD.Core.PixelFormat.R16i: return 2;
                case DDD.Core.PixelFormat.R16ui: return 2;
                case DDD.Core.PixelFormat.R32f: return 4;
                case DDD.Core.PixelFormat.R32i: return 4;
                case DDD.Core.PixelFormat.R32ui: return 4;

                case DDD.Core.PixelFormat.RG8: return 2;
                case DDD.Core.PixelFormat.RG8i: return 2;
                case DDD.Core.PixelFormat.RG8ui: return 2;
                case DDD.Core.PixelFormat.RG16: return 4;
                case DDD.Core.PixelFormat.RG16f: return 4;
                case DDD.Core.PixelFormat.RG16i: return 4;
                case DDD.Core.PixelFormat.RG16ui: return 4;
                case DDD.Core.PixelFormat.RG32f: return 8;
                case DDD.Core.PixelFormat.RG32i: return 8;
                case DDD.Core.PixelFormat.RG32ui: return 8;

                case DDD.Core.PixelFormat.RGB8: return 1;
                case DDD.Core.PixelFormat.RGB8i: return 1;
                case DDD.Core.PixelFormat.RGB8ui: return 1;
                case DDD.Core.PixelFormat.RGB16: return 2;
                case DDD.Core.PixelFormat.RGB16f: return 2;
                case DDD.Core.PixelFormat.RGB16i: return 2;
                case DDD.Core.PixelFormat.RGB16ui: return 2;
                case DDD.Core.PixelFormat.RGB32f: return 4;
                case DDD.Core.PixelFormat.RGB32i: return 4;
                case DDD.Core.PixelFormat.RGB32ui: return 4;

                case DDD.Core.PixelFormat.RGBA8: return 4;
                case DDD.Core.PixelFormat.RGBA8i: return 4;
                case DDD.Core.PixelFormat.RGBA8ui: return 4;
                case DDD.Core.PixelFormat.RGBA16: return 8;
                case DDD.Core.PixelFormat.RGBA16f: return 8;
                case DDD.Core.PixelFormat.RGBA16i: return 8;
                case DDD.Core.PixelFormat.RGBA16ui: return 8;
                case DDD.Core.PixelFormat.RGBA32f: return 8;
                case DDD.Core.PixelFormat.RGBA32i: return 8;
                case DDD.Core.PixelFormat.RGBA32ui: return 8;

                case DDD.Core.PixelFormat.RGB9e5: return 4;
                case DDD.Core.PixelFormat.R11G11B10f: return 4;
                case DDD.Core.PixelFormat.RGB10A2: return 4;
                case DDD.Core.PixelFormat.RGB10A2ui: return 4;

                case DDD.Core.PixelFormat.Depth: return 1;

                default: throw new NotImplementedException ("Sorry");
            }
        }

        /// <summary>
        /// DDDの<see cref="DDD.Core.PixelType"/>型のオブジェクトを<seealso cref="global::OpenTK.Graphics.OpenGL.PixelType"/>型に変換します
        /// </summary>
        /// <param name="type"><see cref="DDD.Core.PixelType"/>型オブジェクト</param>
        /// <returns><seealso cref="global::OpenTK.Graphics.OpenGL.PixelType"/>型オブジェクト</returns>
        public static global::OpenTK.Graphics.OpenGL.PixelType ToGL (this DDD.Core.PixelType type) {
            switch (type) {
                case DDD.Core.PixelType.Byte: return global::OpenTK.Graphics.OpenGL.PixelType.UnsignedByte;
                case DDD.Core.PixelType.SByte: return global::OpenTK.Graphics.OpenGL.PixelType.Byte;
                case DDD.Core.PixelType.Short: return global::OpenTK.Graphics.OpenGL.PixelType.Short;
                case DDD.Core.PixelType.UShort: return global::OpenTK.Graphics.OpenGL.PixelType.UnsignedShort;
                case DDD.Core.PixelType.Int: return global::OpenTK.Graphics.OpenGL.PixelType.Int;
                case DDD.Core.PixelType.UInt: return global::OpenTK.Graphics.OpenGL.PixelType.UnsignedInt;
                case DDD.Core.PixelType.Float: return global::OpenTK.Graphics.OpenGL.PixelType.Float;
                default: throw new NotImplementedException ("Sorry");
            }
        }

        /// <summary>
        /// <see cref="ImageFilter"/>を対応するOpenTKの型に変換します
        /// </summary>
        /// <param name="format">DDDの<see cref="ImageFilter"/>型</param>
        /// <returns>OpenTKの<seealso cref="global::OpenTK.Graphics.OpenGL.TextureMagFilter"/>型</returns>
        public static global::OpenTK.Graphics.OpenGL.TextureMagFilter ToGL_Mag (this ImageFilter format) {
            switch (format) {
                case ImageFilter.Nearest: return global::OpenTK.Graphics.OpenGL.TextureMagFilter.Nearest;
                case ImageFilter.Linear: return global::OpenTK.Graphics.OpenGL.TextureMagFilter.Linear;
                default: throw new NotImplementedException ("Sorry");
            }
        }

        /// <summary>
        /// <see cref="ImageFilter"/>を対応するOpenTKの型に変換します
        /// </summary>
        /// <param name="format">DDDの<see cref="ImageFilter"/>型</param>
        /// <returns>OpenTKの<seealso cref="global::OpenTK.Graphics.OpenGL.TextureMinFilter"/>型</returns>
        public static global::OpenTK.Graphics.OpenGL.TextureMinFilter ToGL_Min (this ImageFilter format) {
            switch (format) {
                case ImageFilter.Nearest: return global::OpenTK.Graphics.OpenGL.TextureMinFilter.LinearMipmapNearest;
                case ImageFilter.Linear: return global::OpenTK.Graphics.OpenGL.TextureMinFilter.LinearMipmapLinear;
                default: throw new NotImplementedException ("Sorry");
            }
        }

        /// <summary>
        /// <see cref="DDD.Core.TextureWrapMode"/>を対応するOpenTKの型に変換します
        /// </summary>
        /// <param name="wrap">DDDの<see cref="DDD.Core.TextureWrapMode"/>型</param>
        /// <returns>OpenTKの<seealso cref="global::OpenTK.Graphics.OpenGL.TextureWrapMode"/>型</returns>
        public static global::OpenTK.Graphics.OpenGL.TextureWrapMode ToGL (this DDD.Core.TextureWrapMode wrap) {
            switch (wrap) {
                case DDD.Core.TextureWrapMode.Repeat: return global::OpenTK.Graphics.OpenGL.TextureWrapMode.Repeat;
                case DDD.Core.TextureWrapMode.Clamp: return global::OpenTK.Graphics.OpenGL.TextureWrapMode.Clamp;
                default: throw new NotImplementedException ("Sorry");
            }
        }

        /// <summary>
        /// <see cref="DepthComparisonFunction"/>を対応するOpenTKの型に変換します
        /// </summary>
        /// <param name="func">DDDの<see cref="DepthComparisonFunction"/>型</param>
        /// <returns>OpenTKの<seealso cref="global::OpenTK.Graphics.OpenGL.DepthFunction"/>型</returns>
        public static global::OpenTK.Graphics.OpenGL.DepthFunction ToGL (this DepthComparisonFunction func) {
            switch (func) {
                case DepthComparisonFunction.Always: return global::OpenTK.Graphics.OpenGL.DepthFunction.Always;
                case DepthComparisonFunction.Equal: return global::OpenTK.Graphics.OpenGL.DepthFunction.Equal;
                case DepthComparisonFunction.Greater: return global::OpenTK.Graphics.OpenGL.DepthFunction.Greater;
                case DepthComparisonFunction.GreaterEqual: return global::OpenTK.Graphics.OpenGL.DepthFunction.Gequal;
                case DepthComparisonFunction.Less: return global::OpenTK.Graphics.OpenGL.DepthFunction.Less;
                case DepthComparisonFunction.LessEqual: return global::OpenTK.Graphics.OpenGL.DepthFunction.Lequal;
                case DepthComparisonFunction.Never: return global::OpenTK.Graphics.OpenGL.DepthFunction.Never;
                case DepthComparisonFunction.NotEqual: return global::OpenTK.Graphics.OpenGL.DepthFunction.Notequal;
                default: throw new NotImplementedException ("Sorry");
            }
        }

        /// <summary>
        /// <see cref="ColorBlendFunction"/>を対応するOpenTKの型に変換します
        /// </summary>
        /// <remarks>
        /// ブレンド式に変換するときに使用します
        /// </remarks>
        /// <param name="func">DDDの<see cref="ColorBlendFunction"/>型</param>
        /// <returns>OpenTKの<seealso cref="global::OpenTK.Graphics.OpenGL.BlendEquationMode"/>型</returns>
        public static global::OpenTK.Graphics.OpenGL.BlendEquationMode ToGL1 (this ColorBlendFunction func) {
            switch (func) {
                case ColorBlendFunction.Replace: return global::OpenTK.Graphics.OpenGL.BlendEquationMode.FuncAdd;
                case ColorBlendFunction.Add: return global::OpenTK.Graphics.OpenGL.BlendEquationMode.FuncAdd;
                case ColorBlendFunction.Alpha: return global::OpenTK.Graphics.OpenGL.BlendEquationMode.FuncAdd;
                case ColorBlendFunction.AlphaAdd: return global::OpenTK.Graphics.OpenGL.BlendEquationMode.FuncAdd;
                case ColorBlendFunction.AlphaDarken: return global::OpenTK.Graphics.OpenGL.BlendEquationMode.FuncAdd;
                case ColorBlendFunction.AlphaPremultiplied: return global::OpenTK.Graphics.OpenGL.BlendEquationMode.FuncAdd;
                case ColorBlendFunction.Modulate: return global::OpenTK.Graphics.OpenGL.BlendEquationMode.FuncAdd;
                case ColorBlendFunction.ModulateInverse: return global::OpenTK.Graphics.OpenGL.BlendEquationMode.FuncAdd;
                case ColorBlendFunction.ModulateX2: return global::OpenTK.Graphics.OpenGL.BlendEquationMode.FuncAdd;
                default: throw new NotImplementedException ("Sorry");
            }
        }

        /// <summary>
        /// <see cref="ColorBlendFunction"/>を対応するOpenTKの型に変換します
        /// </summary>
        /// <remarks>
        /// ブレンドファクター(src)に変換するときに使用します
        /// </remarks>
        /// <param name="func">DDDの<see cref="ColorBlendFunction"/>型</param>
        /// <returns>OpenTKの<seealso cref="global::OpenTK.Graphics.OpenGL.BlendingFactorSrc"/>型</returns>
        public static global::OpenTK.Graphics.OpenGL.BlendingFactorSrc ToGL2 (this ColorBlendFunction func) {
            switch (func) {
                case ColorBlendFunction.Replace: return global::OpenTK.Graphics.OpenGL.BlendingFactorSrc.One;
                case ColorBlendFunction.Add: return global::OpenTK.Graphics.OpenGL.BlendingFactorSrc.One;
                case ColorBlendFunction.Alpha: return global::OpenTK.Graphics.OpenGL.BlendingFactorSrc.SrcAlpha;
                case ColorBlendFunction.AlphaAdd: return global::OpenTK.Graphics.OpenGL.BlendingFactorSrc.SrcAlpha;
                case ColorBlendFunction.AlphaDarken: return global::OpenTK.Graphics.OpenGL.BlendingFactorSrc.Zero;
                case ColorBlendFunction.AlphaPremultiplied: return global::OpenTK.Graphics.OpenGL.BlendingFactorSrc.One;
                case ColorBlendFunction.Modulate: return global::OpenTK.Graphics.OpenGL.BlendingFactorSrc.DstColor;
                case ColorBlendFunction.ModulateInverse: return global::OpenTK.Graphics.OpenGL.BlendingFactorSrc.One;
                case ColorBlendFunction.ModulateX2: return global::OpenTK.Graphics.OpenGL.BlendingFactorSrc.DstColor;
                default: throw new NotImplementedException ("Sorry");
            }
        }

        /// <summary>
        /// <see cref="ColorBlendFunction"/>を対応するOpenTKの型に変換します
        /// </summary>
        /// <remarks>
        /// ブレンドファクター(dst)に変換するときに使用します
        /// </remarks>
        /// <param name="func">DDDの<see cref="ColorBlendFunction"/>型</param>
        /// <returns>OpenTKの<seealso cref="global::OpenTK.Graphics.OpenGL.BlendingFactorSrc"/>型</returns>
        public static global::OpenTK.Graphics.OpenGL.BlendingFactorDest ToGL3 (this ColorBlendFunction func) {
            switch (func) {
                case ColorBlendFunction.Replace: return global::OpenTK.Graphics.OpenGL.BlendingFactorDest.Zero;
                case ColorBlendFunction.Add: return global::OpenTK.Graphics.OpenGL.BlendingFactorDest.One;
                case ColorBlendFunction.Alpha: return global::OpenTK.Graphics.OpenGL.BlendingFactorDest.OneMinusSrcAlpha;
                case ColorBlendFunction.AlphaAdd: return global::OpenTK.Graphics.OpenGL.BlendingFactorDest.One;
                case ColorBlendFunction.AlphaDarken: return global::OpenTK.Graphics.OpenGL.BlendingFactorDest.OneMinusSrcAlpha;
                case ColorBlendFunction.AlphaPremultiplied: return global::OpenTK.Graphics.OpenGL.BlendingFactorDest.OneMinusSrcAlpha;
                case ColorBlendFunction.Modulate: return global::OpenTK.Graphics.OpenGL.BlendingFactorDest.Zero;
                case ColorBlendFunction.ModulateInverse: return global::OpenTK.Graphics.OpenGL.BlendingFactorDest.OneMinusSrcColor;
                case ColorBlendFunction.ModulateX2: return global::OpenTK.Graphics.OpenGL.BlendingFactorDest.SrcColor;
                default: throw new NotImplementedException ("Sorry");
            }
        }
    }
}
